---
import Sidebar from '@/components/Sidebar.astro'
import Layout from '@/layouts/Layout.astro'
import { makeSortedCategoryEntries } from '@/utils/content'
import { compareUrlPaths } from '@/utils/url'
import Navbar from '@/components/Navbar.astro'

const { frontmatter, headings } = Astro.props

const sortedPages = makeSortedCategoryEntries().flatMap(
    (category) => category[1],
)
const pageIndex = sortedPages.findIndex((page) =>
    compareUrlPaths(page.id, Astro.url.pathname),
)
const nextDoc =
    pageIndex === sortedPages.length - 1
        ? undefined
        : sortedPages.at(pageIndex + 1)
const prevDoc = pageIndex === 0 ? undefined : sortedPages.at(pageIndex - 1)

const headers: Array<
    Array<{
        depth: number
        text: string
        slug: string
    }>
> = [[]]

if (headings.length > 0) {
    let currentDepth = headings[0].depth

    for (const heading of headings) {
        if (heading.depth === currentDepth) {
            headers.at(-1)?.push(heading)
        } else {
            headers.push([heading])
            currentDepth = heading.depth
        }
    }
}
---

<style is:global>
    @import './Doc.css';
</style>

<Layout>
    <column self-="grow">
        <Navbar />
        <row self-="grow" gap-="1">
            <div id="sidebar-container" class="mobile-hidden">
                <Sidebar />
            </div>
            <article box-="square" shear-="top">
                <header is-="row" align-="between">
                    <div is-="badge" variant-="background0">
                        <h1>{frontmatter.title}</h1>
                    </div>
                </header>
                <row gap-="1" self-="grow">
                    <div id="scroll-container">
                        <main id="main-content">
                            <slot />
                            <div id="doc-pagination">
                                {
                                    prevDoc && (
                                        <a
                                            href={`/${prevDoc.id}`}
                                            class="prev"
                                            box-="round"
                                            shear-="top"
                                            tabindex="0">
                                            <div is-="typography-block">
                                                <span
                                                    is-="badge"
                                                    variant-="background0">
                                                    <row gap-="1">
                                                        <span>←</span>
                                                        <code>&lt;C-p&gt;</code>
                                                        <span>Previous</span>
                                                    </row>
                                                </span>
                                            </div>
                                            <span pad-="1 0">
                                                {prevDoc.id.split('/')[0]}/
                                                {prevDoc.data.title}
                                            </span>
                                        </a>
                                    )
                                }
                                {
                                    nextDoc && (
                                        <a
                                            href={`/${nextDoc.id}`}
                                            class="next"
                                            box-="round"
                                            shear-="top"
                                            tabindex="0">
                                            <row
                                                align-="start end"
                                                is-="typography-block">
                                                <span
                                                    is-="badge"
                                                    variant-="background0">
                                                    <row gap-="1">
                                                        <span>Next</span>
                                                        <code>&lt;C-n&gt;</code>
                                                        <span>→</span>
                                                    </row>
                                                </span>
                                            </row>
                                            <span pad-="1 0">
                                                {nextDoc.id.split('/')[0]}/
                                                {nextDoc.data.title}
                                            </span>
                                        </a>
                                    )
                                }
                            </div>
                        </main>
                    </div>
                </row>
            </article>
        </row>
        <div id="mobile-nav">
            <button variant-="background1" id="menu-button">
                &#xeb86; Menu
            </button>
            <button id="docs-button">&#xf15b; Docs</button>
        </div>
    </column>
</Layout>

<!-- Vim Navigation -->
<script>
    import {
        applyVimNavigation,
        isUserTyping,
        vimFocusElement,
    } from '@/utils/vim'

    const queryString =
        '#main-content > [tabindex="0"], #main-content li[tabindex="0"]'

    const vimTabbableElements: NodeListOf<HTMLElement> =
        document.querySelectorAll(queryString)

    let currentElement: HTMLElement | null = null

    const findFirstFocusableElement = () =>
        Array.from(vimTabbableElements).find((el) => {
            const rect = el.getBoundingClientRect()

            return rect.top >= 0 && rect.bottom <= window.innerHeight
        })

    window.addEventListener('keydown', (e) => {
        // Don't navigate if the user is typing
        if (isUserTyping()) {
            return
        }

        // ctrl-o -> "navigate out"
        if (e.key === 'o' && e.ctrlKey) {
            e.preventDefault()
            window.history.back()
        }

        // ctrl-i -> "navigate in"
        if (e.key === 'i' && e.ctrlKey) {
            e.preventDefault()
            window.history.forward()
        }

        if (e.key === 'l') {
            const elementToFocus =
                currentElement ?? findFirstFocusableElement() ?? null

            if (elementToFocus) {
                vimFocusElement(elementToFocus)
            }
        }

        const nextHref = document.querySelector('.next')?.getAttribute('href')
        const prevHref = document.querySelector('.prev')?.getAttribute('href')

        if (e.key === 'n' && e.ctrlKey && nextHref) {
            window.location.href = nextHref
        }

        if (e.key === 'p' && e.ctrlKey && prevHref) {
            window.location.href = prevHref
        }
    })

    const mainContent = document.getElementById('main-content') as HTMLElement

    applyVimNavigation(mainContent, queryString, (element) => {
        currentElement = element
    })
</script>

<!-- Mobile Navigation -->
<script>
    const menuButton = document.getElementById(
        'menu-button',
    ) as HTMLButtonElement
    const docsButton = document.getElementById(
        'docs-button',
    ) as HTMLButtonElement
    const sidebarContainer = document.getElementById(
        'sidebar-container',
    ) as HTMLDivElement
    const article = document.querySelector('article') as HTMLElement

    menuButton.addEventListener('click', () => {
        sidebarContainer.classList.remove('mobile-hidden')
        article.classList.add('mobile-hidden')
        menuButton.setAttribute('variant-', '')
        docsButton.setAttribute('variant-', 'background1')
    })

    docsButton.addEventListener('click', () => {
        sidebarContainer.classList.add('mobile-hidden')
        article.classList.remove('mobile-hidden')
        menuButton.setAttribute('variant-', 'background1')
        docsButton.setAttribute('variant-', '')
    })
</script>
